package cn.lhn.ridersclub.service;

import cn.lhn.ridersclub.dto.AccountDto;
import cn.lhn.ridersclub.dto.CommentDto;
import cn.lhn.ridersclub.entity.*;
import cn.lhn.ridersclub.mapper.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

@Service
public class CommentServiceImpl implements CommentService {

    private final CommentMapper commentMapper;

    private final CommentSupportMapper commentSupportMapper;

    private final PaperMapper paperMapper;

    private final AccountMapper accountMapper;

    private final SubjectCommentMapper subjectCommentMapper;

    private final GradeService gradeService;

    private final RedisService redisService;

    private final AccountFollowMapper accountFollowMapper;

    public CommentServiceImpl(CommentMapper commentMapper, CommentSupportMapper commentSupportMapper, PaperMapper paperMapper, AccountMapper accountMapper, SubjectCommentMapper subjectCommentMapper, GradeService gradeService, RedisService redisService, AccountFollowMapper accountFollowMapper) {
        this.commentMapper = commentMapper;
        this.commentSupportMapper = commentSupportMapper;
        this.paperMapper = paperMapper;
        this.accountMapper = accountMapper;
        this.subjectCommentMapper = subjectCommentMapper;
        this.gradeService = gradeService;
        this.redisService = redisService;
        this.accountFollowMapper = accountFollowMapper;
    }

    @Override
    public void addComment(String content, Long paperId, Long accountId) {

        //  查询paper是否存在
        Paper paper = paperMapper.selectById(paperId);
        if (paper == null) {
            throw new RuntimeException("文章不存在");
        }

        //  查看账号是否存在
        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        //  添加数据
        int i = commentMapper.insert(new Comment(0L, content, paperId, accountId, LocalDateTime.now()));
        if (i == 0) {
            throw new RuntimeException("添加失败");
        }
    }

    private CommentDto toCommentDto(Comment comment) {

        if (comment == null) {
            return null;
        }

        String accountName = accountMapper.getNicknameById(comment.getAccountId());

        return CommentDto
                .builder()
                .id(comment.getId())
                .accountId(comment.getAccountId())
                .accountName(accountName)
                .content(comment.getContent())
                .time(comment.getCreateTime())
                .supportCount(commentSupportMapper.getCommentSupportCount(comment.getId()))
                .commentCount(subjectCommentCount(comment.getId()))
                .build();
    }


    public AccountDto toAccountDto(Account account) {

        //  等级
        Grade grade = gradeService.getGrade(account.getId());
        Long maxGradeValue = gradeService.getMaxGradeValue(grade.getGrade());

        //  文章输数量
        QueryWrapper<Paper> qwp = new QueryWrapper<>();
        qwp.eq("account_id", account.getId());
        Long paperCount = paperMapper.selectCount(qwp);

        //  关注数和粉丝数
        QueryWrapper<AccountFollow> qw = new QueryWrapper<>();
        qw.eq("fans_id", account.getId());
        Long followCount = accountFollowMapper.selectCount(qw);

        qw = new QueryWrapper<>();
        qw.eq("account_id", account.getId());
        Long fansCount = accountFollowMapper.selectCount(qw);

        return AccountDto
                .builder()
                .id(account.getId())
                .nickname(account.getNickname())
                .gender(account.getGender())
                .profile(account.getProfile())
                .birth(account.getBirth())
                .createTime(account.getCreateTime())
                .grade(grade.getGrade())
                .currentGradeValue(grade.getCurrentGradeValue())
                .maxGradeValue(maxGradeValue)
                .paperCount(paperCount)
                .followCount(followCount)
                .fansCount(fansCount)
                .build();
    }

    @Override
    public void deleteComment(Long commentId, Long accountId) {

        //  删除评论
        QueryWrapper<Comment> qw = new QueryWrapper<>();
        qw.eq("id", commentId);
        qw.eq("account_id", accountId);
        int i = commentMapper.delete(qw);
        if (i == 0) {
            throw new RuntimeException("删除失败");
        }

        //  删除子评论
        QueryWrapper<SubjectComment> qwsc = new QueryWrapper<>();
        qwsc.eq("comment_id", commentId);
        subjectCommentMapper.delete(qwsc);
    }

    @Override
    public CommentDto getComment(Long commentId) {
        return toCommentDto(commentMapper.selectById(commentId));
    }

    @Override
    public List<CommentDto> listComment(Long paperId, Long startId) {
        List<Comment> list = commentMapper.listComment(paperId, startId);
        List<CommentDto> l = new ArrayList<>();
        for (Comment comment : list) {
            l.add(toCommentDto(comment));
        }
        return l;
    }

    @Override
    public Long getCommentCount(Long paperId) {
        QueryWrapper<Comment> qw = new QueryWrapper<>();
        qw.eq("paper_id", paperId);
        return commentMapper.selectCount(qw);
    }

    @Override
    public void supportComment(Long commentId, Long accountId) {

        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            throw new RuntimeException("评论不存在");
        }

        QueryWrapper<CommentSupport> qw = new QueryWrapper<>();
        qw.eq("comment_id", commentId);
        qw.eq("account_id", accountId);
        CommentSupport support = commentSupportMapper.selectOne(qw);
        if (support != null) {
            throw new RuntimeException("请勿重复提交");
        }

        commentSupportMapper.insert(new CommentSupport(null, commentId, accountId));
    }

    @Override
    public void deleteSupportComment(Long commentId, Long accountId) {

        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            throw new RuntimeException("评论不存在");
        }

        QueryWrapper<CommentSupport> qw = new QueryWrapper<>();
        qw.eq("comment_id", commentId);
        qw.eq("account_id", accountId);
        CommentSupport support = commentSupportMapper.selectOne(qw);
        if (support == null) {
            throw new RuntimeException("记录不存在");
        }

        commentSupportMapper.deleteById(support);
    }

    @Override
    public Boolean isSupportComment(Long commentId, Long accountId) {
        QueryWrapper<CommentSupport> qw = new QueryWrapper<>();
        qw.eq("comment_id", commentId);
        qw.eq("account_id", accountId);
        CommentSupport support = commentSupportMapper.selectOne(qw);
        return support != null;
    }

    @Override
    public CommentDto getMostHotCommentByPaperId(Long paperId) {

        //  查询对应文章的所有评论
        QueryWrapper<Comment> qw = new QueryWrapper<>();
        qw.eq("paper_id", paperId);
        List<Comment> list = commentMapper.selectList(qw);

        long maxCount = 0L;
        Long id = 0L;

        //  查询最大点赞数的ID
        for (Comment comment : list) {
            Long count = commentSupportMapper.getCommentSupportCount(comment.getId());
            if (maxCount <= count) {
                maxCount = count;
                id = comment.getId();
            }
        }

        return toCommentDto(commentMapper.selectById(id));
    }

    @Override
    public Comment getMostHotComment(Long paperId) {//  查询对应文章的所有评论
        QueryWrapper<Comment> qw = new QueryWrapper<>();
        qw.eq("paper_id", paperId);
        List<Comment> list = commentMapper.selectList(qw);

        long maxCount = 0L;
        Comment c = null;

        //  查询最大点赞数的ID
        for (Comment comment : list) {
            Long count = commentSupportMapper.getCommentSupportCount(comment.getId());
            if (count != null && maxCount <= count) {
                maxCount = count;
                c = comment;
            }
        }

        return c;
    }

    @Override
    public List<Long> listHostTopIdByPaperId(Long paperId) {
        return new ArrayList<>();
    }

    @Override
    public void addSubjectComment(Long commentId, Long accountId, String content) {

        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            throw new RuntimeException("评论不存在");
        }
        SubjectComment subjectComment = SubjectComment
                .builder()
                .id(null)
                .commentId(comment.getId())
                .accountId(account.getId())
                .content(content)
                .createTime(LocalDateTime.now())
                .build();

        subjectCommentMapper.insert(subjectComment);
    }

    @Override
    public void deleteSubjectComment(Long subjectCommentId, Long accountId) {

        Account account = accountMapper.selectById(accountId);
        if (account == null) {
            throw new RuntimeException("账号不存在");
        }

        SubjectComment subjectComment = subjectCommentMapper.selectById(subjectCommentId);
        if (subjectComment == null) {
            throw new RuntimeException("评论不存在");
        }

        subjectCommentMapper.deleteById(subjectCommentId);
    }

    @Override
    public List<SubjectComment> listSubjectComment(Long commentId) {

        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            throw new RuntimeException("评论不存在");
        }

        QueryWrapper<SubjectComment> qw = new QueryWrapper<>();
        qw.eq("comment_id", comment.getId());
        return subjectCommentMapper.selectList(qw);
    }

    @Override
    public Long subjectCommentCount(Long commentId) {
        QueryWrapper<SubjectComment> qw = new QueryWrapper<>();
        qw.eq("comment_id", commentId);
        return subjectCommentMapper.selectCount(qw);
    }
}
